package ar.uba.dc.tl.mylanga.semantic;

import ar.uba.dc.tl.mylanga.exception.FunctionWithoutReturnException;
import ar.uba.dc.tl.mylanga.node.*;

public class FunctionMustReturnRule extends SemanticRule {

    public FunctionMustReturnRule(PProgram program) {
        super("FunctionMustReturnRule", program);
    }

    @Override
    public void check() {
        this.getProgram().apply(this);
    }

    @Override
    public void caseAFunctionDefinition(AFunctionDefinition node) {
        super.caseAFunctionDefinition(node);

        PStatement body = node.getBody();

        if (body instanceof AReturnStatement) {
            return;
        }
        if (body instanceof ACompoundStatement) {
            PStatement statement = body;
            while (statement instanceof ACompoundStatement) {
                ACompoundStatement compound = (ACompoundStatement)statement;
                if (compound.getStatements().size() > 0) {
                    statement = compound.getStatements().getLast();
                } else {
                    break;
                }
            }
            //statement is the last statement in the function.
            if (statement instanceof AReturnStatement) {
                return;
            }
        }

        throw new FunctionWithoutReturnException(node.getName());
    }

}
